home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d18 / turbcomm.arc / TC.PAS < prev   
Pascal/Delphi Source File  |  1989-06-30  |  31KB  |  812 lines

  1. { File: TC.PAS }
  2. Program TurboComm;
  3.    { Program's function: Test out COMMLIB.INC }
  4.    { Some code has been added that will only compile under }
  5.    { Turbo Pascal Version 3.0 or greater }
  6.    { Search for 'Version 3.0', comment that code out, and }
  7.    { un-comment out the code marked '< 3.0' }
  8.  
  9.  
  10.   { Turn off ^C checking, to enhance speed somewhat }
  11.   {$C-}
  12.  
  13.    Label EndProgram;
  14.  
  15.  
  16.    Const
  17.       ProgramName = 'TurboComm';
  18.       KeyFileName : String[80] = 'TC';
  19.       ProgramVer = '1.2';
  20.       Esc = ^[;
  21.       CarrReturn = ^M;
  22.       ReverseScreen = ^['[?5h';
  23.       UnreverseScreen = ^['[?5l';
  24.       SaveCursor = ^['7';
  25.       RestoreCursor = ^['8';
  26.       Bold = ^['[1m';
  27.       Off  = ^['[m';
  28.       Reverse = ^['[7m';
  29.       ReverseBold = ^['[7;1m';
  30.       PrinterReady    = ^['[?10n';  { Printer is turned on }
  31.       PrinterNotReady = ^['[?11n';  { Printer if not turned on }
  32.       TermVT102 = ^['[?6c';
  33.       TermVT125 = ^['[?12;7;0c';
  34.       TermVT220 = ^['[?62;1;2c';
  35.       TermVT240 = ^['[?62;1;2;3;4c';
  36.       SendRetries = 10;             { Max number of times to resend a char }
  37.       VT200Keys : Boolean = True;   { Use the VT2xx function key values }
  38.  
  39.       FileNameLen = 62;             { Turbo Pascal Version 3.0 Only }
  40.                                     { i.e. It supports pathnames    }
  41.  
  42. {     FileNameLen = 14;             { Turbo Pascal Version < 3.0    }
  43.  
  44.    Type
  45.       STR80 = String[80];
  46.       StringLong = String[150];
  47.  
  48.  
  49.    Var
  50.       DummyLogical : Boolean;
  51.       Counter, Counter2, CurrentBaud, CtrlCCheck : Integer;
  52.       TermID : STR80;     { String returned on host after Terminal ID request }
  53.       FKey_Dir : Str80;         { Modification for V1.2 - FKey_Dir }
  54.       FileOpen  : Boolean;
  55.       ReGISOn   : Boolean;   { Are we running the Poly-ReGIS emulator? }
  56.       DisplayOn : Boolean;   { Output to screen? }
  57.       PrinterOn : Boolean;   { Output to printer? }
  58.       LoggingOn : Boolean;   { Output to file? }
  59.       FileVar : Text;        { File type for sending or receiving }
  60.       Filename : String[FileNameLen];
  61.       CursorRow, CursorCol : Integer;  { Supplied by GetCursorPosition }
  62.  
  63.  
  64.       { These are the different data registers used for MSDOS interrupts }
  65.    Type
  66.  
  67.       __Regs = Record case Integer of
  68.                1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags : INTEGER);
  69.                2: (AL,AH,BL,BH,CL,CH,DL,DH : Byte);
  70.                end;
  71.  
  72.    Var
  73.       __Registers : __Regs;
  74.       __SaveRegisters : __Regs;   { Use this to save the initial reg values }
  75.  
  76.  
  77.  
  78.    {$I FUNKEY.INC }       { Include function key input definiton }
  79.  
  80.  
  81.  
  82.  
  83.  
  84.    Procedure WriteStatus(OutputString : StringLong);
  85.       { Get current cursor position, write status on bottom of screen,
  86.         return to previous cursor position }
  87.  
  88.       Begin
  89.          Write(SaveCursor);      { Save cursor position }
  90.          GotoXY(1,24);
  91.          ClrEol;
  92.          Write(OutputString);
  93.          Write(RestoreCursor);      { Restore cursor position }
  94.          End; { Procedure WriteStatus }
  95.  
  96.  
  97.    Procedure SetCtrlCCheck;
  98.       { Read startup value of Control-C checking, set off, save value }
  99.       { N.B. This is the equivalent of the MS-DOS BREAK=OFF command   }
  100.       {      and is required to run this program.                     }
  101.       Begin
  102.          { Get initial value and save to variable }
  103.          __Registers.AH := $33;
  104.          __Registers.AL := 0;
  105.          Intr($21,__Registers);
  106.          CtrlCCheck := __Registers.DL;
  107.          
  108.          { Set checking off }
  109.          __Registers.AH := $33;
  110.          __Registers.AL := 1;
  111.          __Registers.DL := 0;
  112.          Intr($21,__Registers);
  113.  
  114.          End; { Procedure SetCtrlCCheck }
  115.          
  116.  
  117.    Procedure ResetCtrlCCheck;
  118.       { Reset the original Control C checking value to startup value }
  119.       { See previous procedure for explaination. }
  120.       Begin
  121.          __Registers.AH := $33;
  122.          __Registers.AL := 1;
  123.          __Registers.DL := CtrlCCheck;
  124.          Intr($21,__Registers);
  125.          End;  { Procedure ResetCtrlCCheck }
  126.  
  127.  
  128.    Function CheckPrinter : Boolean;
  129.       { Check the status of the printer port }
  130.       Begin
  131.          If Port[$43] = 100
  132.             Then CheckPrinter := True
  133.             Else CheckPrinter := False;
  134.          End; { Function CheckPrinter }
  135.  
  136.  
  137.    Procedure CheckFunctionStatus(FunctionStatus : Boolean;
  138.                                  FunctionName : STR80);
  139.       { Check the status of a function's value, and print on error,
  140.         given the name of the function that was called. }
  141.       Var
  142.          OutputLine : STR80;
  143.  
  144.       Begin
  145.          If Not FunctionStatus
  146.             Then
  147.               Begin
  148.                  OutputLine := Bold+FunctionName+' not successful.'+Off;
  149.                  WriteStatus(OutputLine);
  150.                  End  { If file not opened }
  151.  
  152.          End;  { Procedure CheckFunctionStatus }
  153.  
  154.  
  155.    {$I COMMLIB.INC }      { Include communications function definitions }
  156.    {$I CHECKESC.INC }     { Check all escape sequences for specials }
  157.    {$I GETVIDLN.INC }     { Read video memory for screen line }
  158.    {$I GETENV.INC }        { Procedure to get MS-DOS environmental variable }
  159.    {$I REDEFINE.INC }     { Include function key redefinition routines }
  160.  
  161.    Procedure PrintScreen;
  162.       { Read the current screen from video memory, and dump to printer }
  163.       { N.B. If ReGIS is running, let it handle print screens itself }
  164.       Var
  165.          VidChar : Char;
  166.          LineCounter, ColCounter : Integer;
  167.          VideoString,DummyString : StringLong;
  168.          LineDrawingOn : Boolean;
  169.       Begin
  170.  
  171.          If CheckPrinter And (Not ReGISOn)   { The printer is ready }
  172.             Then                             { and we're not running ReGIS }
  173.                Begin
  174.                   { First set up video screen width by getting a line twice }
  175.                   DummyString := GetVidLine(1);
  176.                   DummyString := GetVidLine(1);
  177.                   { Now set printer width according to screen width }
  178.                   If VideoScreenWidth = 132
  179.                      Then Write(Lst,^[,'[4w')
  180.                      Else Write(Lst,^[,'[0w');
  181.  
  182.                   LineDrawingOn := False;
  183.                   Write(Lst,^O);   { Turn printer graphics off }
  184.  
  185.                   { Now get all the screen lines and print them }
  186.                   Write(ReverseScreen);  { Reverse the screen until done }
  187.                   For LineCounter := 1 to 24 Do
  188.                      Begin
  189.                         VideoString := GetVidLine(Linecounter); { Get line }
  190.  
  191.           { Move source code left, because of length of lines }
  192.           For ColCounter := 1 to Length(VideoString) Do
  193.              Begin  { Checking and printing character }
  194.                 VidChar := VideoString[ColCounter];
  195.                 If Ord(VidChar) < 32
  196.                    Then { We've got a graphics character to print }
  197.                         If LineDrawingOn
  198.                            Then Write(Lst,Chr(Ord(VidChar) + 95))
  199.                            Else Begin
  200.                               Write(Lst,^N);  { Printer to graphics mode }
  201.                               Write(Lst,Chr(Ord(VidChar) + 95));
  202.                               LineDrawingOn := True;
  203.                               End  { We had to turn on graphics mode }
  204.                         Else If Not LineDrawingOn
  205.                                 Then Write(Lst,VidChar) { normal character }
  206.                                 Else Begin
  207.                                    Write(Lst,^O);
  208.                                    Write(Lst,VidChar);
  209.                                    LineDrawingOn := False;
  210.                                    End; { We had to turn off graphics & print }
  211.                 End; { FOR ColCounter loop to print video line }
  212.                 Writeln(Lst);  { Send a carriage return, line feed to printer }
  213.                 Delay(2);   { Give it a short rest }
  214.                         End; { FOR LineCounter loop to print video line }
  215.                   Write(UnReverseScreen);
  216.                   Write(Lst,^O);  { Always turn line drawing off when done }
  217.                   End;
  218.          End; { Procedure PrintScreen }
  219.  
  220.  
  221. {   Const     { Turbo Pascal Version < 3.0 }
  222. {      ParamStrArray : Array[1..5] of STR80 = ('','','','','');  { nulls }
  223.  
  224. {   Var       { Turbo Pascal Version < 3.0 }
  225. {      ParamCount : Byte;
  226.  
  227. {   Procedure ParseCmdLine;    { Turbo Pascal Version < 3.0 }
  228.       { Read any user command line, and return it as a string }
  229.       { This loads the array ParamStrArray }
  230. {     Var
  231.          CL : STR80 absolute cseg:$80;
  232.          CLCopy : STR80;
  233.       begin
  234.          ParamCount := 0;
  235.          CLCopy := CL;
  236.          While CLCopy > '' Do
  237.             Begin
  238.                While CLCopy[1] = ' ' Do
  239.                   CLCopy := Copy(CLCopy,2,Length(CLCopy) - 1);
  240.                ParamCount := ParamCount + 1;
  241.                While (CLCopy[1] <> ' ') And (CLCopy > '') Do
  242.                   Begin
  243.                      ParamStrArray[ParamCount] := ParamStrArray[ParamCount]
  244.                                                      + CLCopy[1];
  245.                      CLCopy := Copy(CLCopy,2,Length(CLCopy) - 1);
  246.                      End; { While the next char isn't a space }
  247.  {              End; { While there are more characters to get }
  248.  
  249.  {        end; { Procedure ParseCmdLine }
  250.  
  251.  {  Function ParamStr(I : Byte) : STR80;   { Turbo Pascal Version < 3.0 }
  252.       { Given the index number, return the parameter string from the array }
  253.  {     Begin
  254.          ParamStr := ParamStrArray[I];
  255.          End; { Function ParamStr }
  256.  
  257.  
  258.    Function DisplayMenu : Boolean;
  259.       { Check command line for 'T' --> go directly to terminal emulation }
  260.       {                                (i.e. don't display opening menu  }
  261.       { Also check for initial baud rate setting }
  262.  
  263.       Type
  264.          ValidBaudType = Array [1..8] of String[4];
  265.  
  266.       Const
  267.          NumBauds  = 8;
  268.          ValidBaud : ValidBaudType = ('110','150','300',
  269.                      '600','1200','2400',
  270.                      '4800','9600');
  271.  
  272.       Var
  273.          Counter,BaudIndex : Integer;
  274.          TempStr : STR80;
  275.  
  276.       Begin
  277.          DisplayMenu := True;
  278.          CurrentBaud := DefaultBaud;
  279.          VT200Keys := True;
  280.  
  281.          { Read through command line for valid input parameters }
  282.          For Counter := 1 to ParamCount Do
  283.             Begin
  284.                TempStr := ParamStr(Counter);
  285.                If UpCase(TempStr[1]) = 'T'
  286.                   Then DisplayMenu := False
  287.                   Else If (TempStr = 'VT100') Or
  288.                           (TempStr = 'vt100')
  289.                           Then VT200Keys := False
  290.                           Else If TempStr[1] = '@'
  291.                                   Then KeyFileName := Copy(TempStr,2,80)
  292.                                   Else
  293.                           { Compare ParamStr against valid baud rates }
  294.                              For BaudIndex := 1 to NumBauds Do
  295.                                 If TempStr = ValidBaud[BaudIndex]
  296.                                    Then Val(TempStr,CurrentBaud,Counter2);
  297.                End; { For Counter loop }
  298.  
  299.             End; { Function DisplayMenu }
  300.  
  301.  
  302.    Function MSDosVersion : Real;
  303.       { Return the current MS-DOS version number }
  304.       begin
  305.          __Registers.AX := $3000;
  306.          MSDos( __Registers );
  307.          MSDosVersion := __Registers.AL + __Registers.AH/100;
  308.          end; { Function MSDosVersion }
  309.  
  310.  
  311.    Procedure WriteScr(Var CharToPrint : Char);
  312.       { Write a character to the screen }
  313.       { This could be replaced by the standard Write statement, but }
  314.       { it runs about 5 percent faster. }
  315.       { Save and restore the values of the registers }
  316.       Begin
  317.          __SaveRegisters := __Registers;
  318.          With __Registers Do Begin
  319.             CX := 0;
  320.             DI := 0;       { Function code for Console Out }
  321.             AL := Ord(CharToPrint);
  322.             End;
  323.          Intr(24,__Registers);
  324.          __Registers := __SaveRegisters;
  325.          End; { Procedure WriteScr }
  326.  
  327.  
  328.    Procedure DisplayHelp;
  329.       { Display help text on the screen }
  330.  
  331.       Var
  332.          OutputLine : StringLong;
  333.          OldVideoLine : StringLong;   { Old value of 24th line Declaration }
  334.  
  335.       Begin
  336.          OutputLine := Off+'Press '+Bold+'<F4>'+Off+
  337.                        ' for command mode: '+Bold+
  338.                'C'+Off+'lose '+Bold+
  339.                'D'+Off+'isconnect '+Bold+
  340.                'P'+Off+'rinter '+Bold+
  341.                'Q'+Off+'uit '+Bold+
  342.                'R'+Off+'eceive '+Bold+
  343.                'S'+Off+'end '+
  344.                'e'+Bold+'X'+Off+'it';
  345.          OldVideoLine := GetVidLine(24);  { Old value of 24th line assignment }
  346.  
  347.          WriteStatus(OutputLine);
  348.          End; { Procedure DisplayHelp }
  349.  
  350.  
  351.    Procedure InitTermID;
  352.       { Initialize the global variable TermID, based on whether we're running
  353.         ReGIS emulation software or operating in normal mode. }
  354.       Var
  355.          InputString : STR80;
  356.  
  357.       Begin
  358.          ReGISOn := False;
  359.          InputString := '';
  360.  
  361.          Write(Esc,'PpR(p)',Esc,'\');  { Send out ReGIS report request }
  362.  
  363.          { ReGIS should return something like '[0,0]'.  If ReGIS isn't on,   }
  364.          { nothing should be returned.  So just check for the standard chars }
  365.          For Counter := 1 to 50 Do
  366.              If ReadKey
  367.                Then
  368.                   InputString := InputString + InString;
  369.  
  370.                   If Pos(']',InputString) > 0
  371.                      Then Begin
  372.                         ReGISOn := True;
  373.                         If VT200Keys
  374.                         Then       { Graphics and VT200 Class }
  375.                            TermID := TermVT240
  376.                         Else       { Graphics and VT100 Class }
  377.                            TermID := TermVT125;
  378.                         End
  379.                      Else Begin
  380.                         ReGISOn := False;
  381.                         If VT200Keys
  382.                         Then       { No Graphics and VT200 Class }
  383.                            TermID := TermVT220
  384.                         Else       { No Graphics and VT100 Class }
  385.                            TermID := TermVT102;
  386.                         End;
  387.  
  388.          ClrScr;
  389.          End;
  390.  
  391.  
  392.    Function Space(X : Byte) : STR80;
  393.       { BASIC-like function to return x number of spaces }
  394.       Var
  395.          TempString : STR80;
  396.          Counter : Integer;
  397.       Begin
  398.          TempString := '';
  399.          For Counter := 1 to X Do TempString := TempString + ' ';
  400.          Space := TempString;
  401.          End; { Function Space }
  402.  
  403.  
  404.    Function MoveLeft(X : Integer) : STR80;
  405.       { Move the cursor left X number of positions }
  406.       Var
  407.          TempString : STR80;
  408.       Begin
  409.          Str(X,TempString);
  410.          MoveLeft := ^[ + '[' + TempString + 'D';
  411.          End; { Function MoveLeft }
  412.  
  413.  
  414.    Procedure CloseFile;
  415.       { When done receiving text file, close it }
  416.       Var
  417.          OldVideoLine : StringLong;   { Old value of 24th line Declaration }
  418.  
  419.       Begin
  420.          If FileOpen Then
  421.             Begin
  422.                Write(SaveCursor);
  423.                Close(FileVar);
  424.                OldVideoLine := GetVidLine(24);
  425.                GotoXY(1,24);
  426.                ClrEol;
  427.                NormVideo;
  428.                Write('Closing any open files');
  429.                LowVideo;
  430.                Delay(1000);
  431.                GotoXY(1,24);
  432.                ClrEol;
  433.                Write(OldVideoLine);  { Restore old value of 24th line }
  434.                Write(RestoreCursor);
  435.                FileOpen := False;
  436.                LoggingOn := False;
  437.                End;
  438.          End; { Procedure CloseFile }
  439.  
  440.  
  441.    Procedure SendFile;
  442.       { Send a text file from disk via comm line }
  443.  
  444.       Var
  445.          Line : StringLong;
  446.          OldVideoLine : StringLong;   { Old value of 24th line Declaration }
  447.          Counter : Byte;
  448.  
  449.       Begin
  450.          { First check that a file isn't already open }
  451.          If FileOpen Then
  452.             Begin
  453.                CloseFile;
  454.                FileOpen := False;
  455.                End; { If they had a file open }
  456.  
  457.          OldVideoLine := GetVidLine(24);  { Old value of 24th line assignment }
  458.  
  459.          Write(ReverseScreen);     { Give screen white background }
  460.          NormVideo;
  461.          { Print prompt, then back up for filename input }
  462.          Write(SaveCursor);  { Save the current cursor position }
  463.          GotoXY(1,24);
  464.          ClrEol;
  465.          Write(ReverseBold,'File to send: ',Space(FileNameLen),
  466.                MoveLeft(FileNameLen));
  467.  
  468.         { This procedure breaks the rule that says you shouldn't mix }
  469.         { level 1 console input with level 2 console input (Read()s) }
  470.         Read(FileName);
  471.         GotoXY(1,24);
  472.         ClrEol;
  473.         LowVideo;
  474.         Write(OldVideoLine);             { Restore old value of 24th line }
  475.         Write(RestoreCursor);  { Restore cursor position from save }
  476.         LowVideo;
  477.         Write(UnreverseScreen);
  478.         ClearLevel2Buffer;    { clear level 2 keyboard buffer }
  479.         Assign(FileVar, FileName);
  480.         {$i-} Reset(FileVar); {$i+}
  481.         If IOResult = 0 then
  482.            Begin
  483.               FileOpen := True;
  484.               While Not Eof(fileVar) Do
  485.                  Begin
  486.                     Read(FileVar,Line);
  487.                     For Counter := 1 to Length(Line) Do Begin
  488.                        Counter2 := 0;     { Initialize  # times sent counter }
  489.                        While (Not WriteCommChar(Line[Counter])) And
  490.                           (Counter2 < SendRetries) Do
  491.                              Begin
  492.                                 Counter2 := Counter2 + 1;
  493.                                 Delay(10);
  494.                                 End; { if you couldn't send that character }
  495.                        If ReadCommChar Then WriteScr(CommIn.Char);
  496.                        End; { print line a character at a time }
  497.                        DummyLogical := WriteCommChar(CarrReturn);
  498.                        While ReadCommChar Do WriteScr(CommIn.Char);
  499.                     Readln(FileVar);
  500.                     End;
  501.               End { If file exists }
  502.            Else
  503.                  WriteStatus(^G+^G+Bold+'File not found'+Off);
  504.         CloseFile;
  505.  
  506.         End; { Procedure SendFile }
  507.  
  508.  
  509.    Procedure ReceiveFile;
  510.       Var
  511.          OldVideoLine : StringLong;   { Old value of 24th line Declaration }
  512.  
  513.       { Log the data coming in from the host to a file }
  514.  
  515.       Begin
  516.          OldVideoLine := GetVidLine(24);  { Old value of 24th line assignment }
  517.  
  518.          Write(ReverseScreen);     { Give screen white background }
  519.          NormVideo;
  520.          Write(SaveCursor);  { Save current cursor position }
  521.          GotoXY(1,24);
  522.          ClrEol;
  523.  
  524.          { Print prompt, then back up for filename input }
  525.          Write(ReverseBold,'File to Receive: ',Space(FileNameLen),
  526.                MoveLeft(FileNameLen));
  527.  
  528.         { This procedure breaks a rule that says you shouldn't mix }
  529.         { level 1 console input with level 2 console input (Read()s) }
  530.         Read(FileName);
  531.         GotoXY(1,24);
  532.         ClrEol;
  533.         LowVideo;
  534.         Write(OldVideoLine);             { Restore old value of 24th line }
  535.         Write(RestoreCursor);  { Restore cursor position from save }
  536.         LowVideo;
  537.         Write(UnReverseScreen);   { Return screen to white on black }
  538.         Assign(FileVar,FileName);
  539.         {$i-} Rewrite(FileVar); {$i+}
  540.         If IOResult <> 0
  541.            Then
  542.               Begin
  543.                  Writeln;
  544.                  WriteStatus(^G+^G+Bold+'File could not be opened!'+Off);
  545.                  End
  546.            Else
  547.               Begin
  548.                  FileOpen := True;
  549.                  LoggingOn := True;
  550.                  End; { If file could be opened }
  551.  
  552.         ClearLevel2Buffer;    { clear level 2 keyboard buffer }
  553.  
  554.         End; { Procedure ReceiveFile }
  555.  
  556.  
  557.    Procedure TestKeystroke;
  558.       { They've hit F4, so they want a special function. }
  559.       { Get the next keystroke to determine the function. }
  560.  
  561.       Begin
  562.          { Don't come back til you've got a keystroke }
  563.          While Not ReadKey Do;
  564.  
  565.          { Translate keystroke }
  566.          If Length(InString) = 1  { it wasn't a function key }
  567.             Then Case UpCase(InString[1]) Of
  568.                     'C': CloseFile;
  569.                     'D': CheckFunctionStatus(DisconnectModem,'Disconnecting');
  570.                     'P': PrinterOn := Not PrinterOn;  { Toggle printer mode }
  571.                     'Q': Begin
  572.                             DummyLogical := DisconnectModem;
  573.                             Write(CarrReturn,Bold,'Disconnecting      ');
  574.                             FunCode := Dum100;                { Exit Program }
  575.                             End; { They pressed 'Q' }
  576.                     'R': ReceiveFile;
  577.                     'S': SendFile;
  578.                     'X': FunCode := Dum100;    { Exit program, trips Until }
  579.                     Else { Display help text }
  580.                        DisplayHelp;
  581.                     End { Check keystroke }
  582.             Else If (FunCode In Redefinables)  { in set of redefinable keys }
  583.                     Then RedefineKey(FunCode)
  584.                     Else WriteStatus('That function key may not be redefined.');
  585.  
  586.  
  587.          End; { Procedure TestKeystroke }
  588.  
  589.  
  590.    Function StartupDisplay : Boolean;
  591.       { Display initial help information for TurboComm program }
  592.       { and wait until they press either Do or Exit Key }
  593.  
  594.       Const
  595.          StartingCol = 20;
  596.  
  597.       Var
  598.          ValidKey : Boolean;
  599.  
  600.       Begin
  601.          { Display help text }
  602.          ClrScr;
  603.          NormVideo;
  604.          GotoXY(16,1);
  605.          Write(^[,'#3',ProgramName);  { Double size - top half }
  606.          GotoXY(16,2);
  607.          Write(^[,'#4',ProgramName);  { Double size - bottom half }
  608.          GotoXY(19,3);
  609.          Write('Rainbow MS-DOS Terminal Emulation Software');
  610.          LowVideo;
  611.          GotoXY(29,4);
  612.          Write('Public Domain software');
  613.          GotoXY(22,5);
  614.          Write('by Stew Stryker, RONNIE Support Group');
  615.          GotoXY(10,7);
  616.          Write('Press ',Bold,'<DO>',Off,'   for terminal emulation',Off);
  617.          GotoXY(16,8);
  618.          Write(Bold,'<HELP>',Off,' for additional information');
  619.          GotoXY(16,9);
  620.          Write(Bold,'<EXIT>',Off,' to exit to operating system');
  621.          GotoXY(15,12);
  622.          Write(^[,'[4m','Immediate Commands while in terminal emulation',Off);
  623.          GotoXY(1,13);
  624.          Write(Bold,'<F4>',Off,' followed by highlighted character:');
  625.          GotoXY(StartingCol,14);
  626.          Write(Bold,'C',Off,'lose open file');
  627.          GotoXY(StartingCol,15);
  628.          Write(Bold,'D',Off,'isconnect modem');
  629.          GotoXY(StartingCol,16);
  630.          Write(Bold,'P',Off,'rinter toggle on/off');
  631.          GotoXY(StartingCol,17);
  632.          Write(Bold,'Q',Off,'uit, disconnect & exit');
  633.          GotoXY(StartingCol,18);
  634.          Write(Bold,'R',Off,'eceive a file');
  635.          GotoXY(StartingCol,19);
  636.          Write(Bold,'S',Off,'end a file');
  637.          GotoXY(StartingCol,20);
  638.          Write('e',Bold,'X',Off,'it to operating system');
  639.          GotoXY(StartingCol,21);
  640.          Write('any other character displays a short help message');
  641.          GotoXY(10,7);
  642.  
  643.          { Wait until they hit a valid key }
  644.          ValidKey := False;
  645.          While Not ValidKey Do
  646.             Begin
  647.                While Not ReadKey Do;  { Wait for any keystroke }
  648.  
  649.                If (FunCode <> KDo) And (FunCode <> KExit)
  650.                   Then
  651.                      If FunCode = Help
  652.                         Then Begin{ Display disclaimer information }
  653.       GotoXY(1,5);
  654.       Write(^[,'[J');       { Clear to end of screen }
  655.       GotoXY(35,6);
  656.       Writeln(^[,'[4m','DISCLAIMER',^[,'[m');
  657.       Writeln;
  658.       Writeln(^[,'[7C','The author and Digital Equipment Corp absolve themselves of any');
  659.       Writeln(^[,'[7C','possible warranties as to the capabilities of this program, and');
  660.       Writeln(^[,'[7C','specifically disclaim any implied warranties of effectiveness.');
  661.       Writeln(^[,'[7C','This product is provided "as is" and should not be considered a');
  662.       Writeln(^[,'[7C','"Digital-supported" product.');
  663.       Writeln;
  664.       Writeln(^[,'[7C','This program is donated to the public domain.  It may be copied');
  665.       Writeln(^[,'[7C','and disseminated freely for non-profit purposes, if and only if');
  666.       Writeln(^[,'[7C','this disclaimer is included.');
  667.       End { If they pressed Help }
  668.                         Else
  669.                            Begin
  670.                               GotoXY(1,24);
  671.                               Write(^G,^G);
  672.                               Write(Reverse,'Press ',Bold,'<DO>',Off,
  673.                               Reverse,' to start terminal emulation, or ',
  674.                               Bold,'<EXIT>',Off,Reverse,' to exit program',
  675.                               Off);
  676.                               GotoXY(10,7);
  677.                               End
  678.                   Else { They pressed Do or Exit }
  679.                      ValidKey := True;
  680.                End; { Waiting until they hit a valid key }
  681.  
  682.          If FunCode = KDo
  683.             Then StartupDisplay := True
  684.             Else StartupDisplay := False;
  685.  
  686.          End; { Function StartupDisplay }
  687.  
  688.  
  689.    Begin  { Main program }
  690.       If MSDosVersion < 2.05       { This program requires 2.05 or greater }
  691.          Then
  692.             Begin
  693.             NormVideo;
  694.             Writeln(^G,^G,'This program requires MS-DOS 2.05 or higher!!');
  695.             Goto EndProgram;
  696.             End;
  697.  
  698.       SetCtrlCCheck;    { Read startup CtrlC checking value, and set off }
  699.  
  700.       { Read the current comm settings from the non-volatile memory }
  701.       CheckFunctionStatus(ReadCurrentCommSettings,
  702.          'Reading Current Comm Settings');
  703.  
  704.       FKey_Dir := 'TC_DIR'; { Modification for V1.2 - FKey_Dir }
  705.  
  706.       { Initialize comm port, function keys, escape sequence test, & Term ID }
  707.       DummyLogical := ReplaceDefault;  { These work, even though they }
  708.       DummyLogical := InitPort;        { return False. }
  709.       InitFunkeys;     { Define the initial value for function keys }
  710.       InitTermID;      { Check if we're running in ReGIS }
  711.  
  712.       { Display help text and either run or exit program }
  713.       If DisplayMenu                    { Don't by-pass initial menu }
  714.          Then If Not StartupDisplay      { Abort program }
  715.                  Then Goto EndProgram;
  716.  
  717.       ReadKeyFile;     { Read in any function key redefinitions }
  718.  
  719.       CheckFunctionStatus(SetSerial(3,CurrentBaud,DefaultStopBits,
  720.                                     DefaultDataBits,DefaultParity,Chr(0)),
  721.                           'Setting Baud Rate');
  722.       InitEscSeq;      { Define escape sequences to trap }
  723.       PrinterOn := False;
  724.       DisplayOn := True;
  725.       FileOpen := False;
  726.       LoggingOn := False;
  727.  
  728.       CrtInit;     { Display sign-on message }
  729.       ClrScr;
  730.       Write('Baud rate: ');
  731.       NormVideo;
  732.       Writeln(CurrentBaud);
  733.       GotoXY(26,1);
  734.       LowVideo;
  735.       Write('On-Line with ');
  736.       NormVideo;
  737.       Write(ProgramName,' ');
  738.       LowVideo;
  739.       Writeln('(',ProgramVer,')');
  740.       GotoXY(66,1);
  741.       If ReGISOn
  742.          Then If VT200Keys
  743.                  Then Write('VT240')
  744.                  Else Write('VT125')
  745.          Else If VT200Keys
  746.                  Then Write('VT220')
  747.                  Else Write('VT102');
  748.       Writeln(' emulation');
  749.  
  750.       Repeat    { Keep reading/writing until <F4> is pressed }
  751.  
  752.          { Check if a character came in the comm port, then display it. }
  753.             IF ReadCommChar Then
  754.               { If ESC was received, test for special sequences }
  755.               If CommIn.Char = Esc
  756.                  Then CheckEscSeq
  757.                  Else { Check if output goes to printer, screen, or both }
  758.                     Begin
  759.                        If DisplayOn And Not PrinterOn
  760.                           Then WriteScr(CommIn.Char)
  761.                           Else If (Not DisplayOn) And PrinterOn
  762.                                   { i.e. Printer only }
  763.                                   Then Write(Lst,CommIn.Char)
  764.                                   Else Begin
  765.                                      WriteScr(CommIn.Char);
  766.                                      PrintChar(CommIn.Char);
  767.                                      End; { both display and print }
  768.                        If LoggingOn Then Write(FileVar,CommIn.Char);
  769.                        End; { If it wasn't an escape sequence }
  770.  
  771.             { Get the keyboard character and send it out the comm port. }
  772.             If ReadKey Then
  773.                   { Check if a Function key was pressed }
  774.                   If Funcode <> DUM4        { (i.e. Funcode not dummy value) }
  775.                      Then Case Funcode Of
  776.                         BREAK: DummyLogical := SendBreak;
  777.                                                  { Send a Break for
  778.                                                    250 milliseconds }
  779.                         F4:    TestKeystroke;    { Special Function desired ? }
  780.                         PRINT: If FunShiftCode AND 4 = 4  { Held down Ctrl key}
  781.                                   Then PrinterOn := Not PrinterOn
  782.                                   Else PrintScreen;
  783.                         else WriteCommString(InString);
  784.                         End { Case of Funcode }
  785.  
  786.                      Else
  787.                         If VT200Keys And (FunShiftCode AND 4 = 0)
  788.                         { They hit a F11 - F13 while emulating a VT2xx }
  789.                              Then Case InString[1] Of
  790.                                      ^[: WriteCommString(^[+'[23~');   { Esc }
  791.                                      ^H: WriteCommString(^[+'[24~');   { BS  }
  792.                                      ^J: WriteCommString(^[+'[25~');   { Lf  }
  793.                                      Else WriteCommString(InString);
  794.                                      End  { Case statement }
  795.                              Else WriteCommString(InString); {if not in ReGIS}
  796.  
  797.          Until FunCode = DUM100;   { They said to quit  }
  798.  
  799.       CloseFile;   { Close any open files. }
  800.  
  801.       
  802.       DummyLogical := ReplaceDefault;  { Replace default comm port values  }
  803.       WriteKeyFile;     { If a function key def has changed, check saving it }
  804.       ResetCtrlCCheck;  { Restore original value }
  805.       Writeln(Bold,'Returning to MS-DOS operating system',Off);
  806.       CrtExit;
  807.  
  808. EndProgram:
  809.       End.
  810.  
  811.  
  812.